﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace PageAdmin.Utils
{
    /// <summary>
    /// 加密解密的帮助类
    /// </summary>
    public class EncryptHelper
    {
        /// <summary>
        /// md5加密
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string MD5(string s)
        {
            try
            {
                MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
                byte[] data = md5Hasher.ComputeHash(Encoding.UTF8.GetBytes(s));
                StringBuilder sBuilder = new StringBuilder();
                for (int i = 0; i < data.Length; i++)
                {
                    sBuilder.Append(data[i].ToString("x2"));
                }
                return sBuilder.ToString();
            }
            catch (Exception ex)
            {
                throw new Exception("MD5 fail,error:" + ex.Message);
            }
        }

        /// <summary>
        /// 获取字节数组的md5
        /// </summary>
        /// <param name="bytedata"></param>
        /// <returns></returns>
        public static string MD5(byte[] bytedata)
        {
            try
            {
               MD5 md5 = new MD5CryptoServiceProvider();
               byte[] retVal = md5.ComputeHash(bytedata);
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < retVal.Length; i++)
                {
                    sb.Append(retVal[i].ToString("x2"));
                }
                return sb.ToString();
            }
            catch (Exception ex)
            {
                throw new Exception("MD5 fail,error:" + ex.Message);
            }
        }

        /// <summary>
        /// 获取文件的md5摘要
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <returns></returns>
        public static string MD5Abstract(string filePath)
        {
            if(IOHelper.FileIsExists(filePath))
            {
                return null;
            }
            filePath = IOHelper.MapPath(filePath);
            FileStream file = new FileStream(filePath, FileMode.Open);
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] retVal = md5.ComputeHash(file);
            //哈希值是将任意长度的二进制值映射为固定长度的较小二进制值，这个较小的二进制值就哈希值。
            //哈希值是一段数据唯一且极其紧凑的数值表现形式,无论数据多大，数据都很快
            file.Close();

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < retVal.Length; i++)
            {
                sb.Append(retVal[i].ToString("x2"));
            }
            return sb.ToString();
        }

        /// <summary>
        /// 字符串加密，非严格意义加密，仅是byte的转码替换
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string StringEncrypt(string str)
        {
            string mstr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
            if (string.IsNullOrEmpty(str))
            {
                return "";
            }
            byte[] buff = Encoding.UTF8.GetBytes(str);
            int j, k, m;
            int len = mstr.Length;
            StringBuilder sb = new StringBuilder();
            Random r = new Random();
            for (int i = 0; i < buff.Length; i++)
            {
                j = (byte)r.Next(6);
                buff[i] = (byte)((int)buff[i] ^ j);
                k = (int)buff[i] % len;
                m = (int)buff[i] / len;
                m = m * 8 + j;
                sb.Append(mstr.Substring(k, 1) + mstr.Substring(m, 1));
            }
            return sb.ToString();
        }

        /// <summary>
        /// 字符串解密，非严格意义的解密，仅是byte的解码替换
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string StringDecrypt(string str)
        {
            string mstr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
            if (string.IsNullOrEmpty(str))
            {
                return "";
            }
            try
            {
                int j, k, m, n = 0;
                int len = mstr.Length;
                byte[] buff = new byte[str.Length / 2];
                for (int i = 0; i < str.Length; i += 2)
                {
                    k = mstr.IndexOf(str[i]);
                    m = mstr.IndexOf(str[i + 1]);
                    j = m / 8;
                    m = m - j * 8;
                    buff[n] = (byte)(j * len + k);
                    buff[n] = (byte)((int)buff[n] ^ m);
                    n++;
                }
                return System.Text.Encoding.UTF8.GetString(buff);
            }
            catch (Exception ex)
            {
                return "";
            }
        }

        /// <summary>
        /// Des对称加密
        /// </summary>
        /// <param name="strValue"></param>
        /// <param name="key">加密key,最少8位</param>
        /// <returns></returns>
        public static string DesEncrypt(string strValue, string key)
        {
            DESCryptoServiceProvider dsp = new DESCryptoServiceProvider();
            using (MemoryStream memStream = new MemoryStream())
            {
                if (string.IsNullOrEmpty(key))
                {
                    key = "PageAdmin";
                }
                if (key.Length < 8)
                {
                    for(int i=0;i<8- key.Length;i++)
                    {
                        key += "0";
                    }
                }
                byte[] rgbKey = Encoding.UTF8.GetBytes(key.Substring(0, 8));
                byte[] rgbIV = Encoding.UTF8.GetBytes(key.Insert(0, "w").Substring(0, 8));
                CryptoStream crypStream = new CryptoStream(memStream, dsp.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                StreamWriter sWriter = new StreamWriter(crypStream);
                sWriter.Write(strValue);
                sWriter.Flush();
                crypStream.FlushFinalBlock();
                memStream.Flush();
                return Convert.ToBase64String(memStream.GetBuffer(), 0, (int)memStream.Length);
            }
        }

        /// <summary>
        /// DES对称解密
        /// </summary>
        /// <param name="EncValue"></param>
        /// <param name="key">加密key</param>
        /// <returns></returns>
        public static string DesDecrypt(string EncValue, string key)
        {
            try
            {
                DESCryptoServiceProvider dsp = new DESCryptoServiceProvider();
                byte[] buffer = Convert.FromBase64String(EncValue);
                using (MemoryStream memStream = new MemoryStream())
                {
                    if (key == null)
                    {
                        key = "PageAdmin";
                    }
                    if (key.Length < 8)
                    {
                        key = "PageAdmin";
                    }
                    byte[] rgbKey = Encoding.UTF8.GetBytes(key.Substring(0, 8));
                    byte[] rgbIV = Encoding.UTF8.GetBytes(key.Insert(0, "w").Substring(0, 8));
                    CryptoStream crypStream = new CryptoStream(memStream, dsp.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                    crypStream.Write(buffer, 0, buffer.Length);
                    crypStream.FlushFinalBlock();
                    return ASCIIEncoding.UTF8.GetString(memStream.ToArray());
                }
            }
            catch(Exception ex)
            {
                return null;
            }
        }


        /// <summary>
        ///  Rsa非对称加密.
        /// </summary>
        /// <param name="content">加密内容</param>
        /// <param name="publicKey">公钥</param>
        /// <param name="privateKey">私钥</param>
        /// <returns></returns>
        public static string RsaEncrypt(string content, out string publicKey, out string privateKey)
        {
            RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider();
            publicKey = rsaProvider.ToXmlString(false);
            privateKey = rsaProvider.ToXmlString(true);

            UnicodeEncoding ByteConverter = new UnicodeEncoding();
            byte[] DataToEncrypt = ByteConverter.GetBytes(content);
            byte[] resultBytes = rsaProvider.Encrypt(DataToEncrypt, false);
            return Convert.ToBase64String(resultBytes);
        }

        /// <summary>
        /// Rsa非对称解密
        /// </summary>
        /// <param name="content"></param>
        /// <param name="decryptKey">解密key</param>
        /// <returns></returns>
        public static string RsaDecrypt(string content, string decryptKey)
        {
            byte[] dataToDecrypt = Convert.FromBase64String(content);
            RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
            RSA.FromXmlString(decryptKey);
            byte[] resultBytes = RSA.Decrypt(dataToDecrypt, false);
            UnicodeEncoding ByteConverter = new UnicodeEncoding();
            return ByteConverter.GetString(resultBytes);
        }

    }
}
